实验软件:Vivado 2021,Vitis 2021
实验目的:通过串口将程序烧进QSPI接口的Flash中
本次实验在Vitis中由Create Application Project和Create Platform Project两种方法创建新工程
打开 Vivado,进入 Vivado 界面后,点击“Quick Start”栏的 “Create Project”。然后在弹出的创建 Vivado 工程向导界面,点击“Next”。
在工程命名界面。设置工程名为“Mind-Z7020_Vitis_Example“,工程路径根据需要选择,本次我们将该工程放在D://文件夹下。注意,工程名和路径只能由英文字母、数字和下划线组成,不能包含中文、空格以及特殊字符。 勾选“Create project subdirectory”后,点击“Next”:
在此界面设置工程类型。此处我们选择 “RTL Project”。本次实验不需要添加源文件和约束文件,所以勾选“Do not specify sources at this time”。勾选之后会省略后面添加源文件和约束文件的步骤,点击“Next”直接跳到器件选型界面。
器件选型界面。在 Family 栏里选择“Zynq-7000”, Speed 栏选择“-2”,需要注意的是,在 Package 栏选择“clg400”。然后根据所使用的核心板上的 ZYNQ 芯片型号,在下面的器件列表中选择“xc7z020clg400-2”,如下图所示。
显示新建工程的摘要信息,如图所示。在此界面检查前面所设置的工程名称、所选择的器件型号等信息。如果发现工程设置有误,则可以通过 Back 按钮返回到前面的步骤进行修改。检查无误后点击“Finish”,完成工程创建。
工程创建完成后的 Vivado 界面如图所示。
在左侧导航栏(Flow Navigator)中,单击 IP Integrator 下的 Create Block Design。然后在弹出的对话框中指定所创建的 Block Design 的名称,在 Design name 栏中输入“system”。
点击“OK”后,进入图形化设计界面。在Diagram 窗口中点击“+”添加IP核( Intellectual Property(知识产权核),是由 Xilinx(AMD) 或第三方提供的预设计、可复用的硬件功能模块。这些 IP 核封装了特定的硬件功能(如处理器、接口控制器、算法加速器等))。也可以通过快捷键 Ctrl + I,或者右键点击 Diagram 工作区中的空白位置,然后选择“ADD IP”。
弹出 IP 目录后,在搜索栏中键入“zynq”,双击“ZYNQ7 Processing System”,将该IP 添加到设计中。
添加完成后,ZYNQ7 Processing System 模块出现在 Diagram 中,如下图所示:
接下来进行对ZYNQ的配置。通过双击添加的 ZYNQ7 Processing System 模块,进入 ZYNQ7 处理系统的配置界面。其左侧为页面导航,右侧为配置信息面板。如图:
Zynq Block Design:显示了 Zynq 处理系统(PS)的各种可配置块,其中灰色部分是不可修改的,绿色高亮部分是可配置的。进入配置页面可以通过两种方法:直接单击各种可配置块(绿色高亮部分)进入其配置页面进行配置,也可以选择左侧的页面导航进入相应的页面进行配置。 PS-PL Configuration:配置 PS-PL接口,包括 AXI GP、HP 等总线接口。 Peripheral I/O Pins:为不同的 I/O 外设选择 MIO/EMIO。 MIO Configuration:为不同的 I/O 外设具体配置 MIO/EMIO。 Clock Configuration:用于配置 PS 输入时钟、外设时钟,以及 DDR 和 CPU 时钟等。 DDR Configuration:用于设置 DDR 控制器配置信息。 SMC Timing Calculation:用于执行 SMC 时序计算。 Interrupts:用于配置 PS-PL 中断端口。
配置用于打印信息的串口。这里选择 PS 的 UART。点击 Peripheral I/O Pins 页面,出现以下 IO 引脚配置界面。图中根据原理图设置Bank电压(Bank0为3.3V,Bank1为1.8V)。
PS 和外部设备之间的连接主要是通过复用的输入/输出(Multiplexed Input/Output,MIO)来实现的。PS的54个MIO引脚可以用于连接不同的外设接口,如图中的MIO14和MIO15,既可以配置成UART0的引脚接口,也可以配置成 I2C0 或 CAN0 的引脚接口。具体配置成什么外设功能,需要结合开发板。
BANK500 中的 MIO14 和 MIO15 被用作 UART 串口通信的引脚,并最终与底板上的 USB 转串口芯片 CH340X 连接。因此,为了实现串口通信的功能,我们需要在 PS 中将 MIO14 和 MIO15 配置成 UART0 模块的接口引脚。
点击左侧的 MIO Configuration 页面,在右侧展开 I/O Peripherals > UART0,可以看到其具体的引脚配置信息: MIO14 作为 RX 引脚、MIO15 作为 TX 引脚。
配置 UART0 串口通信的波特率。在 General 目录下,可以看到 UART0 的波特率默认115200。通过下拉按钮可以选择其他波特率。
配置QSPI Flash:在Peripheral I/O Pins或MIO Configuratuion中都可以配置。如果在MIO Configuratuion页面中,可以选择Memory Interfaces后勾选Quad SPI Flash,此时Single SS 4-bit IO会自动被选中。
配置 PS 的 DDR3 控制器。点击左侧的 DDR Configuration 页面,在右侧 DDR Controller Configuration 下的“Memory Part”一栏选择 DDR 的器件,选择 MT41K256M16RE-125。核心板上实际的型号是MT41K256M16TW-107。因为提供的选项没有MT41K256M16TW-107这个型号,所以选择了这个兼容的型号。核心板使用了两片MT41K256M16TW-107,每片数据总线线宽16bit,两片就是32bit。其他的配置选项保持默认即可。
配置 PS 的时钟。点击左侧的 Clock Configuration 页面,该界面主要是配置 ZYNQ PS 中的时钟频率。核心板上PS使用的是33.3333MHz的有源晶振。对于 CPU 的时钟、DDR 的时钟以及其它外设的时钟,保持默认设置。
本教程搭建的是ZYNQ7020的嵌入式最小系统,只用到了ZYNQ的PS端。因此我们将PS与PL端交互的接口移除。在 Clock Configuration 页面,展开 PL Fabric Clocks,不勾选 FCLK_CLK0/1/2/3。
点击左侧的 PS-PL Configuration 页面,在右侧展开 General 下,按照下图取消相应的勾选。
配置 ZYNQ7 Processing System 完成,点击“OK”。在Diagram中可以看到ZYNQ7 Processing System IP模块只有DDR和FIXED_IO接口,如图所示。相比刚加入该IP时,ZYNQ7 PS 模块少了四个接口,对应前面取消勾选的几个接口。
点击上图中箭头所指示的位置―Run Block Automation‖,会弹出如下图所示的对话框:
在该界面中我们可以选择自动连接 IP 模块的接口。这次工程只有一个 IP 模块,在左侧确认勾选 processing_system7_0,然后点击“OK”。此时 ZYNQ7 PS 模块引出了两组外部接口,分别是 DDR 和 FIXED_IO,引出的接口将会被分配到 ZYNQ器件具体的引脚上。通过点击 ZYNQ7 PS 模块接口处的“+”展开这两组接口,可以观察各包含哪些信号。
保存当前block design后,可以验证当前设计是否有错误。点击下图箭头所指示的按钮。验证完成后弹出对话框提示没有错误或者关键警告,点击“OK”,如下图所示:
在 Sources 窗口,选中 Design Sources 下的 sysetm.bd,对应前面的 Block Design 文件。右键点击 sysetm.bd,先点击Reset Output Products,之后再点击“Generate Output Products”:
弹出“Generate Output Products”对话框,可以保持 Synthesis Options 默认设置;Run Setings 保持默认或设置为个人电脑处理器最大可使用线程数都可以,然后点击“Generate”来生成设计的综合、实现和仿真文件。在“Generate”过程中会为设计生成所有需要的输出结果。Generate 完成后,在弹出的对话框中点击“OK”。
再次右键点击 system.bd,然后选择“Create HDL Wrapper”。在弹出的对话框中确认勾选“Let Vivado manage wrapper and auto-update”,然后点击“OK”。创建完成后,Design Sources 结构如下图所示:
如果设计中使用到了 PL 的资源,则需要添加引脚约束,并对设计进行综合、实现和生成 Bitstream 文件。由于本工程为最小系统,没有用到 PL 部分,所以无需这些步骤,可以直接将硬件导出到 xsa。
菜单栏选择 File > Export > Export hardware。
在弹出的界面中直接点击next:
由于我们没有生成bitstream 文件,所以在接下来的界面中直接选择第一个选项,如果生成了bitstream 文件,则点击第二个选项“Include bitstream",点击next:
接下来会生成一个.xsa文件,这个文件打包了所有的硬件组件,硬件平台信息,之后用vitis软件或者Linux时都会用到.xsa文件。
最后点击finish完成:
硬件导出完成后,在菜单栏中选择 Tools > Launch vitis IDE,会弹出选择一个命名空间,可以在整个工程文件下新建个vitis文件夹。
在vitis中可以创建两种工程:platform project和application project。
platform project(平台工程)
基于 Vivado 导出的硬件描述文件(.xsa),创建包含以下内容的平台:处理器配置(如 Zynq PS 参数、时钟、外设)、可编程逻辑(PL)的比特流接口、内存映射(DDR 地址空间、外设寄存器)。
生成系统级支持:提供 BSP(Board Support Package)、驱动库和硬件抽象层,供应用程序调用。
一个platfrom project可以对应多个application project。
生成 .xpfm 文件(Xilinx Platform),作为应用工程的依赖。
Application project(应用工程)
对应实际运行的应用程序:在已存在的硬件平台(.xpfm 或 .xsa)上,编写运行在处理器(如 ARM Cortex-A9)上的软件代码
基于platfrom project的硬件平台,无需修改底层配置。支持裸机(Baremetal)、FreeRTOS 或 Linux 应用开发
生成可执行文件(.elf),可下载到 DDR 或烧录到 Flash
| 对比项 | Platform Project | Application Project |
|---|---|---|
| 目的 | 定义硬件基础设施 | 开发运行在硬件上的软件 |
| 输入依赖 | Vivado 导出的 .xsa 文件 | 已存在的平台(.xpfm 或直接 .xsa) |
| 修改频率 | 低频(硬件稳定后很少改动) | 高频(代码迭代开发) |
| 输出文件 | .xpfm(平台描述文件) | .elf(可执行文件) |
| 典型用户 | 硬件工程师/系统架构师 | 软件工程师/嵌入式开发者 |
创建vitis工程时,可以先创建platform project,然后再创建基于该platform project的application project。也可以直接创建application project,但是这时会自动创建一个和该application project关联的platform project。
这里以先创建platform project,再创建application project为例,说一下创建过程。
之后我们的应用工程都是基于创建的一个平台工程所建立。
点击"Browse",选择由vivado生成的xsa文件。
选中之后,下面的选项会自动弹出所使用的操作系统。同时把勾选上"Generate boot components",它会在硬件平台中自动添加fsbl的相关文件。点击"Finish":
至此platfrom project工程创建完成。后续我们创建的应用工程都会基于该平台工程。如图:
如果后续硬件资源文件(.xsa)有修改(通过vivado重新编译生成新的xsa文件),只需update一下硬件资源文件即可,具体操作是在平台工程上右键,弹出的选项中选择“update Hardware specification”。在弹出的窗口中选择新生成的xsa文件。然后对这个平台工程右键操作,选择Build project以重新build该平台工程。
接下来我们需要创建基于该platform project的application project。
通过File->New->Appplication Project创建:
在弹出的界面中点击next:
选择之前创建的platform project:
这里说明一下。如果之前没有创建platform project,可以选择Create a new platform from hardware 页。这样就会创建application project的同时,也创建的platform project。
填写工程名字,点击next:
在接下来的页面可以选择想要的操作系统,本次我们用的裸机,点击next:
在 "Templates" 中选择 "Hello World":由于创建的是一个简单的 "Hello World"工程,所以模板里边有已经生成的代码,可以不用修改,点击 "Finish":
至此新应用工程就创建完了,如图:
点击“hello_world_system”->"hello_world"->src,里面就是软件的.c文件:
右击“hello_world” ,点击“build project”对代码进行编译。如果没有错误,将会生成elf文件。如果有错误,将会在Problems 页面看到错误提示。
将开发板启动模式的拨码开关配置成JTAG模式,使用type-c的usb线将开发板上的JTAG口与电脑进行连接,开发板电源已打开。需要另外准备一根type-c的usb线,将开发板上的PS_UART口和电脑连接。同时在电脑上打开串口工具(如MobaXterm),选择识别出的对应的USB串口,将其波特率设置为115200。
点击“Xilinx”->"XSCT Console",右下角会出现XSCT控制台,输入“connect"命令,此命令是建立与目标硬件(如 我们Zynq-7020 开发板)的调试连接。再输入“targets"命令,此命令是列出当前系统中所有可用的调试目标(处理器/硬件组件)。如果出现图中的回复则说明建立连接成功。
可以通过右键选择Debug as :
或者通过Debug快捷键操作:点击下拉弹出下拉选项,选择需要调试的aplication project :
这时会进入调试模式。默认直接跳转到main()。之后就可以进行单步调试、断点调试:
如果要重新加载程序,可以通过在Debug->[System Project Debug]右键操作,选择中止并relaunch :
Run后,就会在电脑的串口工具上打印出"Hello World"等字符信息。
BOOT.bin的生成有两种方式:
在"hello_world_system" 上右击并bulid project,则会自动先对“hello_world”进行编译生成elf文件,然后将生成的elf文件以及平台工程中的fsbl.elf文件、bitstream文件合并生成BOOT.bin文件。最终烧入到flash的就是这个BOOT.bin文件。
右击“hello_world_system” ,点击"Create Boot Image"。或者通过菜单Xilinx->Create Boot Image进行操作。
选择"Create new BIF file",必须确保"Output format"类型为BIN,如下图:
依次添加如下内容:
fsbl.elf → type: bootloader
system.bit(如果有该文件)→ type: data,选择vivado中生成的.bit文件
hello_world.elf → type: data.
最后点击"Create Image"完成创建。
若出现如图所示的结果则说明已创建成功。
后续再手动生成BOOT.bin文件时,就可以点击"Import form existing BIF file",选择正确文件路径,点击"Create Image ":
点击“Xilinx”->"Program Flash":
在出现的界面中必须确保”Image File“是所生成的BOOT.BIN文件,”Offset“偏移量从0x00000000开始,”Init File“是”fsbl.elf“文件。
说明下BOOT.Bin和fsbl.elf文件的作用:
BOOT.BIN:
启动镜像包:将多个文件合并为一个完整的启动镜像,供BootROM直接读取。
包含内容(按顺序):
FSBL(fsbl.elf):初始化硬件。
比特流文件(system.bit,可选):配置PL逻辑。
应用程序(hello_world.elf):用户代码。
其他组件(如U-Boot、PMUFW等,可选)。
fsbl.elf:
硬件初始化:
配置Zynq的PS(处理器系统)时钟、DDR控制器、外设(如QSPI Flash、UART等)。
加载PL(可编程逻辑)的比特流文件(.bit),配置FPGA逻辑。
加载第二阶段的程序:
从Flash中读取应用程序(如hello_world.elf)到DDR内存,并跳转到其入口地址执行。
点击"Program"后等待几秒,若出现"Flash Operation Successful"则说明烧写QSPI Flash成功。
断电开发板,将启动模式对应的拨码开关设置为QSPI启动模式。将PS_UART串口通过type-c线连接到电脑,并上电。在电脑使用串口工具打开相应的该串口。然后按一下开发板上的复位按键,就能在电脑的串口工具上看到相应的输出信息。